home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / daemons / migd / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-24  |  9.4 KB  |  419 lines

  1. /* 
  2.  * main.c --
  3.  *
  4.  *    Driver for the pdev-based migration/load-average daemon.
  5.  *    Based on the CS 262 project by Thorsten von Eicken and Andreas
  6.  *    Stolcke, spring 1989.
  7.  *
  8.  * Copyright 1989 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /sprite/src/daemons/migd/RCS/main.c,v 2.1 90/09/24 14:45:06 douglis Exp $ SPRITE (Berkeley)";
  20. #endif /* not lint */
  21.  
  22. #include <sprite.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <errno.h>
  27. #include <signal.h>
  28. #include <fs.h>
  29. #include <option.h>
  30. #include <syslog.h>
  31. #include <status.h>
  32. #include <sysStats.h>
  33. #include <sys/file.h>
  34. #include <host.h>
  35. #include "migd.h"
  36. #include "migPdev.h"
  37. #include "global.h"
  38.  
  39.  
  40.  
  41. int debug = 0;
  42.  
  43. Option optionArray[] = {
  44.     {OPT_INT, "D", (char *)&debug, "Set debugging level."},
  45.     {OPT_FALSE, "s", (char *)&migd_Verbose,
  46.          "Disable extra information messages."},
  47.     {OPT_TRUE, "L", (char *)&migd_LogToFiles,
  48.          "Log errors to files rather than to inherited stderr."},
  49.     {OPT_TRUE, "F", (char *)&migd_DontFork,
  50.          "Don't fork when starting or when creating a global daemon."},
  51.     {OPT_FALSE, "S", (char *)&migd_DoStats,
  52.          "Don't gather statistics."},
  53.     {OPT_TRUE, "e", (char *)&migd_NeverEvict,
  54.          "Never evict foreign processes."},
  55.     {OPT_TRUE, "G", (char *)&migd_NeverRunGlobal,
  56.          "Never run the global daemon on this host."},
  57.     {OPT_INT, "C", (char *)&global_CheckpointInterval,
  58.          "Interval for checkpointing state."},
  59. };
  60. static int numOptions = sizeof(optionArray) / sizeof(Option);
  61.  
  62. int    migd_HostID = 0;                      /* My host ID. */
  63. char     *migd_HostName;                 /* My host name. */
  64. static char hostNameBuffer[FS_MAX_NAME_LENGTH];   /* Buffer for host name. */
  65.  
  66. #ifndef SHARED_ERROR_NAME
  67. #define SHARED_ERROR_NAME "/sprite/admin/migd/global-log"
  68. #endif
  69.  
  70. #ifndef LOCAL_ERROR_NAME
  71. #define LOCAL_ERROR_NAME "/sprite/admin/migd/%s.log"
  72. #endif
  73.  
  74. char *migd_GlobalPdevName;             /* Global pdev name,
  75.                            initialized at runtime. */
  76. char *migd_GlobalErrorName = SHARED_ERROR_NAME; /* Global error log. */
  77. char *migd_LocalPdevName;            /* Host-specific pdev name. */
  78.  
  79. char *migd_ProgName;                /* Name invoked by, for
  80.                            msgs. */
  81. int  migd_Pid;                    /* Our process ID, for msgs. */
  82. int  migd_Version = MIG_STATS_VERSION;        /* Our version number. */
  83.  
  84. static int     PrintMemStats();
  85.  
  86.  
  87. /*
  88.  *----------------------------------------------------------------------
  89.  *
  90.  * Debug1 --
  91.  *
  92.  *    For debugging: turns debug variables from non-zero to zero or
  93.  *     from zero to 1.
  94.  *
  95.  * Results:
  96.  *    None.
  97.  *
  98.  * Side effects:
  99.  *    See above.
  100.  *
  101.  *----------------------------------------------------------------------
  102.  */
  103.  
  104. static int
  105. Debug1()
  106. {
  107.     migPdev_Debug = !migPdev_Debug;
  108.     migd_Debug = !migd_Debug;
  109.     global_Debug = !global_Debug;
  110. }
  111.  
  112.  
  113. /*
  114.  *----------------------------------------------------------------------
  115.  *
  116.  * TheEnd --
  117.  *
  118.  *    We've been ordered to quit.  If this is
  119.  *     the first time, try to shut down in an orderly fashion.
  120.  *    If not, just give up.  
  121.  *
  122.  * Results:
  123.  *    None.
  124.  *
  125.  * Side effects:
  126.  *    Sets migd_Quit so contacts will receive error notifications.
  127.  *
  128.  *----------------------------------------------------------------------
  129.  */
  130.  
  131. static int
  132. TheEnd(sigNum)
  133.     int sigNum;
  134. {
  135.     DATE();
  136.     if (migd_Quit) {
  137.     fprintf(stderr, "Multiple signals received: exiting.\n");
  138.     exit(1);
  139.     }
  140.     fprintf(stderr, "Signal %d received: aborting...\n", sigNum);
  141.     if (migd_GlobalMaster) {
  142.     migd_Quit = 1;
  143.     Global_Quit();
  144.     } else {
  145.     exit(1);
  146.     }
  147. }
  148.  
  149.  
  150. /*
  151.  *----------------------------------------------------------------------
  152.  *
  153.  * FatalError --
  154.  *
  155.  *    Record a message in the syslog about a fatal error, then exit.
  156.  *    Try not to take down the other daemons with us.
  157.  *
  158.  * Results:
  159.  *    None.
  160.  *
  161.  * Side effects:
  162.  *    Causes process to terminate.
  163.  *
  164.  *----------------------------------------------------------------------
  165.  */
  166.  
  167. static int
  168. FatalError(sigNum)
  169.     int sigNum;            /* Signal being handled. */
  170. {
  171.     static int gotError = 0;
  172.  
  173.     if (gotError) {
  174.     /*
  175.      * Recursive errors?  Give it up!
  176.      */
  177.     _exit(1);
  178.     }
  179.     gotError = 1;
  180.     if (sigNum == SIGTERM) {
  181.     SYSLOG0(LOG_ERR,
  182.         "terminated by order of global daemon... should be restarted soon.\n");
  183.     if (migd_LogToFiles) {
  184.         fprintf(stderr,
  185.             "terminated by order of global daemon.\n");
  186.     }
  187.     } else {    
  188.     SYSLOG1(LOG_ERR, "Received fatal signal %d: exiting.\n", sigNum);
  189.     if (migd_LogToFiles) {
  190.         fprintf(stderr, "Received fatal signal %d: exiting.\n", sigNum);
  191.     }
  192.     }
  193.     if (migd_GlobalMaster) {
  194.     migd_Quit = 1;
  195.     Global_End();
  196.     } else {
  197.     exit(1);
  198.     }
  199. }
  200.  
  201. #ifdef MEMTRACE
  202. /*
  203.  *----------------------------------------------------------------------
  204.  *
  205.  * PrintMemStats --
  206.  *
  207.  *    Prints a summary of the memory allocator statistics.
  208.  *    Can be called as a signal handler.
  209.  *
  210.  * Results:
  211.  *    None.
  212.  *
  213.  * Side effects:
  214.  *    Statistics are printed on the standard error stream.
  215.  *
  216.  *----------------------------------------------------------------------
  217.  */
  218.  
  219. /*ARGSUSED*/
  220. static int
  221. PrintMemStats(sigNum, sigCode)
  222.     int        sigNum;        /* Ignored. */
  223.     int        sigCode;    /* Ignored. */
  224. {
  225.     Mem_PrintStats();
  226.     Mem_PrintInUse();
  227.     Mem_DumpTrace(2104);
  228. }
  229. #endif /* MEMTRACE */
  230.  
  231.  
  232. /*
  233.  *----------------------------------------------------------------------
  234.  *
  235.  * main --
  236.  *
  237.  *    Driver.
  238.  *
  239.  * Results:
  240.  *    None.
  241.  *
  242.  * Side effects:
  243.  *    None.
  244.  *
  245.  *----------------------------------------------------------------------
  246.  */
  247. main(argc, argv)
  248. int argc;
  249. char *argv[];
  250. {
  251.     int status;
  252.     Host_Entry *hostPtr;
  253.     char buffer[FS_MAX_NAME_LENGTH];    /* For file names. */
  254. #ifdef MEMTRACE
  255.     Mem_TraceInfo traceInfo;
  256. #endif    
  257.  
  258.     argc = Opt_Parse(argc, argv, optionArray, numOptions,
  259.              OPT_ALLOW_CLUSTERING);
  260.  
  261. #ifdef MEMTRACE
  262.     Mem_SetPrintProc(fprintf, (ClientData)stderr);
  263.     traceInfo.size=2104;
  264.     traceInfo.flags=MEM_PRINT_TRACE|MEM_STORE_TRACE;
  265.     Mem_SetTraceSizes(1, &traceInfo);
  266. #endif    
  267.     
  268.  
  269.     /*
  270.      * "Fatal" signals should exit without signalling clients.
  271.      * USR1 toggles debugging.  USR2 should clean up and
  272.      * kill of the per-host daemons too.  
  273.      * Other signals should be ignored completely.  
  274.      */
  275. #ifdef MEMTRACE
  276.     signal(SIGUSR1, PrintMemStats);
  277. #else
  278.     signal(SIGUSR1, Debug1);
  279. #endif
  280.     signal(SIGUSR2, TheEnd);
  281. #ifndef DEBUG
  282.     signal(SIGTERM, FatalError);
  283. #ifndef DEBUG_LIST_REMOVE
  284.     signal(SIGQUIT, FatalError);
  285.     signal(SIGABRT, FatalError);
  286. #endif
  287.     signal(SIGILL,  FatalError);
  288.     signal(SIGFPE,  FatalError);
  289. #endif /* DEBUG */ 
  290.     signal(SIGPIPE, SIG_IGN);
  291.     if (debug <= 2) {
  292.     signal(SIGINT, SIG_IGN);
  293.     signal(SIGTSTP, SIG_IGN);
  294.     signal(SIGSTOP, SIG_IGN);
  295.     signal(SIGTTIN, SIG_IGN);
  296.     signal(SIGTTOU, SIG_IGN);
  297.     }
  298.  
  299.     migd_ProgName = rindex(argv[0], '/');
  300.     if (migd_ProgName){
  301.     migd_ProgName++;
  302.     } else {
  303.     migd_ProgName = argv[0];
  304.     }
  305.     openlog(migd_ProgName, LOG_PID, LOG_DAEMON);
  306.  
  307.     /*
  308.      * Get our hostID and hostname.  Use the physical host just in case
  309.      * someone wants to run us from another host.
  310.      */
  311.  
  312.     status = Proc_GetHostIDs((int *) NULL, &migd_HostID);
  313.     if (status != SUCCESS) {
  314.     Stat_PrintMsg(status, "Proc_GetHostIDs");
  315.     exit(Compat_MapCode(status));
  316.     }
  317.  
  318.     hostPtr = Host_ByID(migd_HostID);
  319.     if (hostPtr == (Host_Entry *) NULL) {
  320.     Host_End();
  321.     fprintf(stderr, "%s: unable to get host information for this host.\n",
  322.         migd_ProgName);
  323.     exit(1);
  324.     }
  325.     migd_HostName = hostNameBuffer;
  326.     (void) strcpy(migd_HostName, hostPtr->name);
  327.  
  328.     migd_GlobalPdevName = Mig_GetPdevName(1);
  329.     migd_LocalPdevName = Mig_GetPdevName(0);
  330.     
  331.     if (migd_LogToFiles) {
  332.     (void) sprintf(buffer, LOCAL_ERROR_NAME, migd_HostName);
  333.     freopen(buffer, "a", stderr);
  334. #ifdef SEEK_REOPEN    
  335.     fseek(stderr, 0L, L_XTND);
  336. #endif /* SEEK_REOPEN */
  337.     if (fcntl(fileno(stderr), F_SETFL, FAPPEND) < 0) {
  338.         perror("fcntl");
  339.     }
  340.     }
  341.     
  342.     
  343.  
  344.     /*
  345.      * Fork off someone to do the real work.
  346.      */
  347.  
  348.     if (!migd_DontFork) {
  349.     int pid = fork();
  350.  
  351.     if (pid < 0) {
  352.         perror("migd");
  353.         exit(1);
  354.     }
  355.     else if (pid > 0) {
  356.         exit(0);
  357.     }
  358.     }
  359.  
  360.     migd_Pid = getpid();
  361.     
  362.     if (debug) {
  363.     extern char *Version();
  364.     int t;
  365.  
  366.     setlinebuf(stderr);
  367.     fprintf(stderr,
  368.         "********************************************************\n");
  369.     fprintf(stderr, "%s: pid %x version %d, %s.\n", migd_ProgName,
  370.         migd_Pid, migd_Version, Version());
  371.     t = time(0);
  372.     fprintf(stderr, "%s: run at %s", migd_ProgName, ctime(&t));
  373.     fprintf(stderr,
  374.         "- - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
  375.  
  376.     migPdev_Debug = debug;
  377.     migd_Debug = debug;
  378.     global_Debug = debug;
  379.     }
  380.  
  381.     /*
  382.      * Get our migration version.
  383.      */
  384.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_GET_VERSION,
  385.                (Address) &migd_Parms.version);
  386.     if (status != SUCCESS) {
  387.     errno = Compat_MapCode(status);
  388.     exit(1);
  389.     }
  390.  
  391.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_GET_STATE,
  392.                (Address) &migd_Parms.criteria);
  393.     if (status != SUCCESS) {
  394.     SYSLOG1(LOG_ERR, "Error in Sys_Stats getting migration state: %s.\n",
  395.         Stat_GetMsg(status));
  396.     exit(Compat_MapCode(status));
  397.     }
  398.  
  399.  
  400.     /*
  401.      * MigPdev_Init must be called before Migd_Init.
  402.      */
  403.     MigPdev_Init();
  404.  
  405.     if(Migd_Init()) {
  406.     exit(1);
  407.     }
  408.  
  409.     
  410.     Migd_HandleRequests();
  411.     Migd_End();
  412.     DATE();
  413.     exit(0);
  414. }
  415.  
  416.  
  417.  
  418.  
  419.